import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing  import PolynomialFeatures
from sklearn.linear_model import LinearRegression
from statsmodels.tsa.arima.model import  ARIMA
from statsmodels.graphics.tsaplots import  plot_acf,plot_pacf



#定义年份和宠物数量数据（万只）
years = np.array([2019,2020,2021,2022,2023]).reshape(-1,1)
cats = np.array([4412, 4862, 5806, 6536, 6980])
dogs = np.array([ 5503, 5222, 5429, 5119, 5175])

#创建数据框架
data = pd.DataFrame({
    'Years':years.flatten(),   #将年转化为一维数组
    'Cats':cats,
    'Dogs':dogs
})

#多项式回归模型
def polynomial_regression(years,pets,degree=2):
    poly = PolynomialFeatures(degree)
    years_poly = poly.fit_transform(years)
    #线性回归拟合
    model = LinearRegression()
    model.fit(years_poly,pets)
    #预测
    pets_pred = model.predict(years_poly)
    return model,pets_pred

#对猫和狗的数据进行回归拟合
model_cat,cats_pred = polynomial_regression(years,cats)
model_dog,dogs_pred = polynomial_regression(years,dogs)

#绘制拟合结果
plt.figure(figsize=(12,6))
#绘制猫的数量
plt.subplot(2,1,1)
plt.scatter(years,cats,color='blue',label='Actual Cats')
plt.plot(years,cats_pred,color='red',label='Predict Cats')
plt.title('Trends Cats')
plt.xlabel('Year')
plt.ylabel('Cat Count(10,000)')
plt.legend()


#绘制狗的数量
plt.subplot(2,1,2)
plt.scatter(years,dogs,color='green',label='Actual Dogs')
plt.plot(years,dogs_pred,color='black',label='Predict Dogs')
plt.title('Trends Dogs')
plt.xlabel('Year')
plt.ylabel('Dogs Count(10,000)')
plt.legend()
plt.tight_layout()
plt.show()

def fit_arima_model(pets,order=(1,1,1,)):
    """差分操作使数据平稳"""
    pets_diff = pets-pets.shift(1)
    pets_diff = pets_diff.dropna()
    """绘制ACF图和PACF图，选择帮助p和q"""
    plot_acf(pets.diff().dropna())
    plot_pacf(pets.diff().dropna())
    plt.show()
    #使用新的（p，d，q）参数
    model = ARIMA(pets,order=order)
    model_fit = model.fit()

    #预测未来值
    forecast = model_fit.forecast(steps=3)   #预测未来三年
    return model_fit,forecast

def combined_forecast(model_trend,poly,forecast_arima,degree=1,weight=0.6):
    """创建未来年份"""
    future_years = np.array([2024,2025,2026]).reshape(-1,1)
    #使用一个PolynomialFeatures生成未来年份的特征
    future_years_poly = poly.transform(future_years)
    #长期趋势预测
    trend_forecast =model_trend.predict(future_years_poly)
    #加权组合趋势预测和ARIMA预测
    combined_forecast  = weight * trend_forecast + (1-weight) * forecast_arima
    return combined_forecast



#调整数据处理和调用顺序
poly = PolynomialFeatures(degree=1)
years_poly = poly.fit_transform(years)
#使用相同的多项式特征对象进行模拟
model_cat = LinearRegression().fit(years_poly,cats)
model_dog = LinearRegression().fit(years_poly,dogs)

#ARIMA建模
arima_model_cat,forecast_cats  =  fit_arima_model(pd.Series(cats),order=(1,1,1))
arima_model_dog,forecast_dogs  =  fit_arima_model(pd.Series(dogs),order=(1,1,1))

#修复联合预测调用
combined_cat_forecast  = combined_forecast(model_cat,poly,forecast_cats,degree=1)
combined_dog_forecast  = combined_forecast(model_dog,poly,forecast_dogs,degree=1)

print("改进后的联合猫数量预测（2024-2026）：",combined_cat_forecast)
print("改进后的联合狗数量预测（2024-2026）：",combined_dog_forecast)

#绘制改进后的联合预测结果
plt.figure(figsize=(12,6))
#绘制猫的联合预测结果
plt.subplot(2,1,1)
plt.scatter(years,cats,color='blue',label='Actual Cats')
plt.plot(years,model_cat.predict(years_poly),color='red',label='Predict Cats')
plt.plot([2024,2025,2026],combined_cat_forecast, color='purple',label='Joint forecasting Cats')
plt.title('Joint prediction of improved cat populations')
plt.xlabel('Year')
plt.ylabel('Cat Count(10,000)')
plt.legend()


#绘制狗的数量
plt.subplot(2,1,2)
plt.scatter(years,dogs,color='green',label='Actual Dogs')
plt.plot(years,model_dog.predict(years_poly),color='black',label='Predict Dogs')
plt.plot([2024,2025,2026],combined_dog_forecast, color='purple',label='Joint forecasting Dogs')
plt.title('Joint prediction of improved dog populations')
plt.xlabel('Year')
plt.ylabel('Dogs Count(10,000)')
plt.legend()
plt.tight_layout()
plt.show()

# 灵敏度分析
# 假设我们已经有了多项式回归模型和预测函数
def polynomial_regression_sensitivity(years, pets, degrees):
    mse_list = []
    for degree in degrees:
        poly = PolynomialFeatures(degree)
        years_poly = poly.fit_transform(years)
        model = LinearRegression().fit(years_poly, pets)
        pets_pred = model.predict(years_poly)
        mse = np.mean((pets - pets_pred) ** 2)
        mse_list.append(mse)
    return mse_list

# 执行灵敏度分析
degrees = [1, 2, 3, 4, 5]
mse_cats = polynomial_regression_sensitivity(years, cats, degrees)
mse_dogs = polynomial_regression_sensitivity(years, dogs, degrees)

# 打印结果
print("Cats MSE for different polynomial degrees:", mse_cats)
print("Dogs MSE for different polynomial degrees:", mse_dogs)

# 可以进一步绘制MSE随度数变化的图表
plt.plot(degrees, mse_cats, label='Cats')
plt.plot(degrees, mse_dogs, label='Dogs')
plt.xlabel('Polynomial Degree')
plt.ylabel('Mean Squared Error')
plt.title('Sensitivity Analysis of Polynomial Degree')
plt.legend()
plt.scatter(degrees, mse_cats, color='red', label='Cats')
plt.scatter(degrees, mse_dogs, color='blue', label='Dogs')
plt.show()